package com.umeox.ota.ui.activity;

import static com.umeox.ota.mvvm.viewModel.MainViewModel.SP_IS_COPY_FILE;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.PermissionRequest;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProviders;

import com.abupdate.iot_libs.OtaAgentPolicy;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.engine.report.LogManager;
import com.abupdate.iot_libs.utils.SPFTool;
import com.abupdate.trace.Trace;
import com.umeox.ota.MainViewBinding;
import com.umeox.ota.R;
import com.umeox.ota.data.local.CustomConfig;
import com.umeox.ota.engine.FotaInitTask;
import com.umeox.ota.engine.PolicyDLWifi;
import com.umeox.ota.gloable.App;
import com.umeox.ota.interact.callback.IOtaOperationFailedInter;
import com.umeox.ota.mvvm.viewModel.MainViewModel;
import com.umeox.ota.service.OtaService;
import com.umeox.ota.ui.filepicker.data.FilePickerConst;
import com.umeox.ota.ui.filepicker.engine.FilePickerBuilder;
import com.umeox.ota.utils.RxTime;
import com.umeox.ota.utils.ThemeColor;
import com.umeox.ota.utils.Utils;
import com.umeox.ota.utils.ViewUitls;

import java.util.ArrayList;



/**
 * @author fighter_lee
 * @date 2017/7/11.
 */

public class MainActivity extends BaseActivity<MainViewBinding, MainViewModel> implements View.OnClickListener, View.OnLongClickListener, View.OnFocusChangeListener {

    private static final String TAG = "MainActivity";
    private ImageView toolbarSetting;
    private TextView mainTitle;
    private ImageView toolbarHome;

    private long startClickTime;
    private int clickCount = 0;
    private int clickMagic = 5;
    private Toolbar toolbar;
    private AlertDialog alertDialog;
    private int thousand = 1000;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (SPFTool.getBoolean(SP_IS_COPY_FILE, false)) {
            return;
        }
        if (mViewModel.fotaInitCompleted()) {
            mViewModel.initData();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        OtaService.startService(OtaService.ACTION_SHOW_NOTIFICATION, "");
    }

    @Override
    protected int genLayoutId(Bundle savedInstanceState) {
        return R.layout.activity_main;
    }

    @Override
    public void genViewModel() {
        mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MainViewModel.class);
    }

    @Override
    protected void initData(Bundle savedInstanceState) {
        mBinding.setViewmodel(mViewModel);
        toolbarSetting = findViewById(R.id.toolbar_setting);
        toolbarHome = mBinding.drawerLayoutInclude.toolbarInclude.findViewById(R.id.toolbar_back);
        mainTitle = findViewById(R.id.iot_main_title);
        mainTitle.setOnClickListener(this);
        mainTitle.setOnLongClickListener(this);
        mBinding.drawerLayoutInclude.viewCenterCircle.setOnClickListener(this);
        mBinding.drawerLayoutInclude.tagCancelId.setOnClickListener(this);
        toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle(R.string.iot_main_title);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        toolbarHome.setImageBitmap(null);

        toolbarHome.setOnClickListener(this);

        toolbarSetting.setImageResource(R.mipmap.ic_main_right);
        toolbarSetting.setOnClickListener(this);

        mViewModel.setCallback(new IOtaOperationFailedInter() {
            @Override
            public void checkFailed(String errorMsg) {
                runOnUiThread(() -> createNormalDialog(MainActivity.this, getString(R.string.tips), errorMsg).show());
            }

            @Override
            public void downloadFailed(String errorMsg) {
                runOnUiThread(() -> {
                    if (getString(R.string.tips_only_wifi_download).equals(errorMsg)) {
                        createDownloadChooseDialog(errorMsg);
                    } else {
                        createNormalDialog(MainActivity.this, getString(R.string.tips), errorMsg).show();
                    }
                });
            }

            @Override
            public void updateFailed(String errorMsg) {
                runOnUiThread(() -> createNormalDialog(MainActivity.this, getString(R.string.tips), errorMsg).show());
            }
        });


        if (mViewModel.fotaInitCompleted()) {
            mViewModel.initData();
        } else {
            mBinding.drawerLayoutInclude.viewCenterCircle.showQueryLocalInfo();
            RxTime.newInstance()
                    .setPeriod(500)
                    .setMinTime(1000)
                    .setTimeout(15 * 1000)
                    .setICondition(() -> null != mViewModel && mViewModel.fotaInitCompleted())
                    .enqueue(true, new RxTime.IEnqueueListener() {
                        @Override
                        public void onComplete() {
                            mViewModel.initData();
                        }

                        @Override
                        public void onTimeOut() {
                            Toast.makeText(MainActivity.this, "初始化失败，请稍后重试", Toast.LENGTH_SHORT).show();
                        }
                    });
        }
        mainTitle.setOnFocusChangeListener(this);
        toolbarHome.setOnFocusChangeListener(this);
        toolbarSetting.setOnFocusChangeListener(this);
        mBinding.drawerLayoutInclude.viewCenterCircle.setOnFocusChangeListener(this);
        mBinding.drawerLayoutInclude.iotVersionDetail.setFocusable(true);
        onFocusChange(mBinding.drawerLayoutInclude.iotVersionDetail, true);
    }

    private void startSetting() {
        if (!FotaInitTask.isCompleted()) {
            return;
        }
        Intent intent = new Intent();
        intent.setClass(this, SetActivity.class);
        startActivity(intent);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FilePickerConst.REQUEST_CODE_DOC && resultCode == RESULT_OK) {
            ArrayList<String> list = data.getStringArrayListExtra(FilePickerConst.KEY_SELECTED_FILES);
            if (list.size() != 1) {
                return;
            }
            final String localPath = list.get(0);
            dialogDismiss();

            //非 zip 文件将 toast 提示文件校验失败
            if (!localPath.endsWith(".zip")) {
                Toast.makeText(this, getString(R.string.tips_upgrade_validate_file_fail), Toast.LENGTH_LONG).show();
                return;
            }

            alertDialog = new AlertDialog.Builder(this)
                    .create();
            View view = LayoutInflater.from(this).inflate(R.layout.dialog_layout, null);
            alertDialog.setOnShowListener(dialog -> {
                Window window = alertDialog.getWindow();
                window.setContentView(view);
                window.findViewById(R.id.dialog_button_positive).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mViewModel.localUpgrade(localPath);
                        dialog.dismiss();
                    }
                });
                window.findViewById(R.id.dialog_button_negative).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });
            });
            alertDialog.show();

        }
    }


    /**
     * 适配电视盒子
     *
     * @param keyCode
     * @param event
     * @return
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                if (mainTitle.isFocused()) {
                    clickShowDeviceInfo(this);
                }
                break;
            case KeyEvent.KEYCODE_BACK:
                if (SPFTool.getBoolean(SP_IS_COPY_FILE, false)) {
                    Utils.moveToBack();
                    return true;
                }
                finish();
                break;
            default:
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onClick(View v) {
        int id = 0;
        if (v.getId() == R.id.view_center_circle) {
            v = mBinding.drawerLayoutInclude.viewCenterCircle.findViewById(R.id.view_circle);
        }
        try {
            id = (Integer) v.getTag();
        } catch (Exception e) {
            id = v.getId();
        }

        switch (id) {
            case R.id.tag_check_id:

                break;

            case R.id.tag_download_id:
                mBinding.drawerLayoutInclude.viewCenterCircle.showDownloadPrepare();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mViewModel.download();
                    }
                }, 500);
                break;

            case R.id.tag_cancel_id:
                mViewModel.cancelDownload();
                break;

            case R.id.tag_update_now_id:
                mBinding.drawerLayoutInclude.viewCenterCircle.showUpgrading();
                new Handler().postDelayed(() -> {
                    mBinding.drawerLayoutInclude.viewCenterCircle.resetProgress();
                    mViewModel.upgrade();
                }, 500);
                break;

            case R.id.toolbar_include:
                break;

            case R.id.iot_main_title:
                clickShowDeviceInfo(this);
                break;

            case R.id.toolbar_setting:
                if (!mViewModel.fotaInitCompleted()) {
                    return;
                }
                PopupMenu popupMenu = new PopupMenu(MainActivity.this, toolbar);
                popupMenu.setGravity(Gravity.RIGHT);
                MenuInflater menuInflater = popupMenu.getMenuInflater();
                menuInflater.inflate(R.menu.main, popupMenu.getMenu());
                if (!CustomConfig.getInstance().localUpdate) {
                    popupMenu.getMenu().findItem(R.id.menu_local_update).setVisible(false);
                }
                popupMenu.setOnMenuItemClickListener(item -> {
                    int itemId = item.getItemId();
                    switch (itemId) {
                        case R.id.menu_settings:
                            if (FotaInitTask.isCompleted()) {
                                dialogDismiss();
                                startSetting();
                            }
                            break;

                        case R.id.menu_local_update:
                            break;

                        case R.id.menu_delete_cache:
                            if (OtaStatusMgr.getInstance().isUpgrading()) {
                                return true;
                            }
                            mViewModel.resetStatus();
                            break;
                        default:
                            break;
                    }
                    return false;
                });
                popupMenu.show();
                break;
            case R.id.tag_reboot_id:
                createChooseAbupdateDialog();
                break;
            case R.id.toolbar_back:
                if (SPFTool.getBoolean(SP_IS_COPY_FILE, false)) {
                    Utils.moveToBack();
                    return;
                }
                finish();
                break;
            default:
                break;
        }
    }

    public void clickShowDeviceInfo(Context context) {
        if (System.currentTimeMillis() - startClickTime < thousand) {
            clickCount++;
        } else {
            clickCount = 0;
        }
        startClickTime = System.currentTimeMillis();
        if (clickCount == clickMagic) {
            PackageManager packageManager = App.sCx.getPackageManager();
            int code = 0;
            String versionName = "";
            try {
                PackageInfo info = packageManager.getPackageInfo(context.getPackageName(), 0);
                code = info.versionCode;
                versionName = info.versionName;
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            String versionInfo = "versionCode: " + code + ", versionName: " + versionName;
            String deviceInfo = "\nmid:" + OtaAgentPolicy.getParamsController().getParams().mid + "\n" + mViewModel.deviceInfo.toString();
            String content = versionInfo + deviceInfo + "\n"
                    + String.format(context.getString(R.string.trace_path), OtaAgentPolicy.getParamsController().getParams().tracePath);
            dialogDismiss();
            LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.dialog_tips_layout, null);
            TextView tv_content = linearLayout.findViewById(R.id.tips_dialog_tv_content);
            TextView tv_title = linearLayout.findViewById(R.id.tips_dialog_tv_title);
            Button btn_ok = linearLayout.findViewById(R.id.tips_dialog_button_positive);
            LinearLayout logCatch = linearLayout.findViewById(R.id.ll_log_catch);
            logCatch.setVisibility(View.VISIBLE);
            logCatch.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    LogManager.getInstance().saveTraceLog();
                    LogManager.getInstance().report();
                    Toast.makeText(App.sCx, App.sCx.getResources().getString(R.string.log_report_success), Toast.LENGTH_SHORT).show();
                    dialogDismiss();
                }
            });
            tv_content.setText(content);
            tv_title.setText(context.getString(R.string.device_info));
            btn_ok.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialogDismiss();
                }
            });
            alertDialog = new AlertDialog.Builder(context)
                    .setView(linearLayout)
                    .setCancelable(false)
                    .create();
            alertDialog.show();
        }
    }


    private AlertDialog createNormalDialog(Context context, String title, String tips) {
        dialogDismiss();
        LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.dialog_tips_layout, null);
        TextView tv_content = linearLayout.findViewById(R.id.tips_dialog_tv_content);
        TextView tv_title = linearLayout.findViewById(R.id.tips_dialog_tv_title);
        Button btn_ok = linearLayout.findViewById(R.id.tips_dialog_button_positive);
        tv_content.setText(tips);
        tv_title.setText(title);
        btn_ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialogDismiss();
            }
        });

        alertDialog = new AlertDialog.Builder(context)
                .setView(linearLayout)
                .setCancelable(false)
                .create();
        return alertDialog;
    }

    private void createDialogWithButtons(String title, String content, String postiveBtnTxt, String negativeBtnTxt, View.OnClickListener positiveBtnListener, View.OnClickListener negativeBtnListener) {
        dialogDismiss();
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(title);
        spannableStringBuilder.setSpan(new ForegroundColorSpan(ThemeColor.textColorPrimary), 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.dialog_tips_layout, null);
        TextView tv_content = linearLayout.findViewById(R.id.tips_dialog_tv_content);
        TextView tv_title = linearLayout.findViewById(R.id.tips_dialog_tv_title);
        Button btn_ok = linearLayout.findViewById(R.id.tips_dialog_button_positive);
        btn_ok.setText(postiveBtnTxt);
        Button btn_cancel = linearLayout.findViewById(R.id.tips_dialog_button_negative);
        btn_cancel.setText(negativeBtnTxt);
        btn_cancel.setVisibility(View.VISIBLE);
        tv_content.setText(content);
        tv_title.setText(spannableStringBuilder);
        btn_ok.setOnClickListener(positiveBtnListener);
        btn_cancel.setOnClickListener(negativeBtnListener);
        alertDialog = new AlertDialog.Builder(this)
                .setView(linearLayout)
                .setCancelable(false)
                .create();
        alertDialog.show();
    }

    public void createDownloadChooseDialog(String tips) {
        createDialogWithButtons(App.sCx.getString(R.string.tips), tips, getString(R.string.ok), getString(R.string.cancel), v -> {
            PolicyDLWifi.chooseToDL();
            dialogDismiss();
            mBinding.drawerLayoutInclude.viewCenterCircle.performClick();
        }, v -> dialogDismiss());
    }

    public void showPolicyDialog(Context context) {
        String s = context.getString(R.string.no_config_policy);
        if (null != mViewModel.policyManager && !TextUtils.isEmpty(mViewModel.policyManager.displayPolicy())) {
            s = mViewModel.policyManager.displayPolicy() == null ? s : mViewModel.policyManager.displayPolicy();
        }
        Trace.d(TAG, "showPolicyDialog() " + s);
        createNormalDialog(context, context.getString(R.string.policy_info), s).show();
    }

    @Override
    public boolean onLongClick(View v) {
        switch (v.getId()) {
            case R.id.iot_main_title:
                showPolicyDialog(this);
                return false;
            default:
                break;
        }
        return false;
    }


    void startPickFile() {
        FilePickerBuilder.getInstance()
                .setTitle(getString(R.string.chosePackage))
                .setMaxCount(1)
                .setActivityTheme(R.style.AppTheme)
                .enableDocSupport(false)
                .setShowAllFile()
                .pickFile(this);
    }


    void showRationaleForLocalUpdate(final PermissionRequest request) {
        dialogDismiss();
        alertDialog = new AlertDialog.Builder(this)
                .setMessage(getString(R.string.permission_write_external_storage))
                .setPositiveButton(getString(R.string.button_allow), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .setNegativeButton(getString(R.string.button_deny), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .create();
        alertDialog.show();
    }


    void showDeniedForExternalStorage() {
        Toast.makeText(this, getResources().getString(R.string.permission_write_external_storage), Toast.LENGTH_SHORT).show();
    }


    void showNeverAskForExternalStorage() {
        dialogDismiss();
        alertDialog = new AlertDialog.Builder(this)
                .setMessage(getResources().getString(R.string.permission_tips))
                .setTitle(getResources().getString(R.string.tips))
                .setPositiveButton(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                })
                .setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .create();
        alertDialog.show();
    }


    void checkVersionAndReadPhone() {
        RxTime.newInstance()
                .setICondition(FotaInitTask::isCompleted)
                .setTimeout(10 * 1000)
                .setPeriod(500)
                .enqueue(false, new RxTime.IEnqueueListener() {
                    @Override
                    public void onComplete() {
                        Trace.d(TAG, "readPhone onTimeOut onComplete ");
                        mViewModel.checkVersion();
                    }

                    @Override
                    public void onTimeOut() {
                        Trace.d(TAG, "readPhone onTimeOut");
                        finish();
                    }
                });
    }

    void readPhone() {
        RxTime.newInstance()
                .setICondition(FotaInitTask::isCompleted)
                .setTimeout(15 * 1000)
                .setPeriod(500)
                .enqueue(false, new RxTime.IEnqueueListener() {
                    @Override
                    public void onComplete() {
                        Trace.d(TAG, "readPhone onTimeOut onComplete ");
                        // TODO: 2019/8/7 需要考虑获取到的 mid 无效的情况
                    }

                    @Override
                    public void onTimeOut() {
                        Log.d(TAG, "readPhone onTimeOut");
                        finish();
                    }
                });
    }


    void showDeniedReadPhone() {
        Log.d(TAG, "readPhone OnPermissionDenied!");
        finish();
    }

    void showNeverAskReadPhone() {
        Log.d(TAG, "readPhone OnNeverAskAgain!");
        finish();
    }


    void showDeniedForCOARSELOCATION() {
        mViewModel.checkVersion();
    }

    void showNeverAskForCOARSELOCATION() {
        mViewModel.checkVersion();
    }



    public void dialogDismiss() {
        if (null != alertDialog && alertDialog.isShowing()) {
            alertDialog.dismiss();
        }
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        mainTitle.setFocusable(true);
        mBinding.drawerLayoutInclude.viewCenterCircle.setFocusable(true);
        toolbarHome.setFocusable(true);
        toolbarSetting.setFocusable(true);
        switch (v.getId()) {
            case R.id.toolbar_setting:
            case R.id.toolbar_back:
            case R.id.iot_main_title:
                if (hasFocus) {
                    v.setBackgroundColor(ViewUitls.darkenColor(ThemeColor.backgroundColor));
                } else {
                    v.setBackgroundColor(ThemeColor.backgroundColor);
                }
                break;
            case R.id.view_center_circle:
                final Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.press_scan);
                if (hasFocus) {
                    mBinding.drawerLayoutInclude.ivPress.setColorFilter(ThemeColor.textColorPrimary);
                    mBinding.drawerLayoutInclude.ivPress.setVisibility(View.VISIBLE);
                    mBinding.drawerLayoutInclude.ivPress.setAnimation(animation);
                    animation.start();
                } else {
                    mBinding.drawerLayoutInclude.ivPress.clearAnimation();
                    mBinding.drawerLayoutInclude.ivPress.setVisibility(View.INVISIBLE);
                }
                break;
            default:
                break;
        }
    }

    public void createChooseAbupdateDialog() {
        createDialogWithButtons(App.sCx.getString(R.string.tips), getString(R.string.ab_update_success_tips), getString(R.string.ok), getString(R.string.cancel), v -> {
            Utils.reboot();
            dialogDismiss();
        }, v -> dialogDismiss());
    }

    @Override
    protected void onDestroy() {
        Trace.d(TAG, "onDestroy");
        super.onDestroy();
    }
}
